<?php

namespace addons\oil\library\traits\model\order;

use addons\oil\exception\Exception;
use addons\sum\model\User;
use addons\oil\model\Order;
use addons\sumprint\library\Service as PrinterService;
use app\admin\model\oil\Store as StoreModel;
use app\admin\model\oil\order\RefundLog;
use app\admin\model\sumprint\Printer as PrinterModel;
use think\Cache;
use think\Db;
use think\Log;


trait OrderOper
{
    public static function getSn($user_id)
    {
        $rand=mt_rand(10000000, 99999999);
        $id = str_pad($user_id, 6, '0', STR_PAD_LEFT);
        return  date('Ym').$id.$rand;
    }

    // 计算订单
    public static function pre($params, $calc_type = 'pre')
    {
        $user = User::info();
        $user_money=$user['money'];
        extract($params);
        //油站信息
        $store=StoreModel::where('id',$store_id)->find();
        $store_name=$store['name'];
        $admin_id=$store['admin_id'];
        //油品信息
        $fuel=Db::name('oil_fuel')->where('id',$fuel_id)->find();
        $fuel_name=$fuel['name'];
        $fuel_price=$fuel['price'];//特价平台价
        $goods_amount=$amount;
        //升数=金额 除以 挂机价
        $fuel_guaji_price=$fuel['guaji_price']??0;//油品挂机价
        if($fuel_guaji_price==0){
            new Exception('油站油品价格错误');
        }
        $litre=$amount/$fuel_guaji_price; //升数
        // 每一步都先四舍五入
        $litre=number_format($litre, 2, '.', '');
        //油站服务费=(特价成本价 减去 特价平台价)乘以升数
        //油站服务费=(挂机价 减去 特价平台价)乘以升数-20240905修改
        $fuel_tjchengben_price=$fuel['tjchengben_price'];//油品-特价成本价
        $dispatch_amount=($fuel_guaji_price-$fuel_price)*$litre;//油站服务费
        // 每一步都先四舍五入
        $dispatch_amount=number_format($dispatch_amount, 2, '.', '');
        //出厂购油价=特价平台价 乘以升数
        $chuchang_amount=$fuel_price*$litre;//出厂购油价
        $chuchang_amount=number_format($chuchang_amount, 2, '.', '');

//        //合计=出厂购油价 +油站服务费
//        //合计=特价平台价 乘以升数+(特价成本价 减去 特价平台价)乘以升数
//        //合计=（特价平台价 + 特价成本价 减去 特价平台价)乘以升数
//        //合计= 特价成本价乘以升数
//        //订单商品总额
//        $total_amount=$fuel_tjchengben_price*$litre;//订单总额

        // 减免特权-如何用户有团队id 则有减免特权
        // 减免特权金额(挂机价-特价成本价)x升数
        $jianmian_money=($fuel_guaji_price-$fuel_tjchengben_price)*$litre;
        // 每一步都先四舍五入
        $jianmian_money=number_format($jianmian_money, 2, '.', '');
        $discount_fee=0;
        if($user['did']>0){
            $discount_fee=$jianmian_money;
        }

        $total_amount=$chuchang_amount+$dispatch_amount-$discount_fee;

        // 每一步都先四舍五入
        $total_amount=number_format($total_amount, 2, '.', '');
        //订单总额
        $total_fee=$total_amount;//订单商品总额+车队服务费
        // 每一步都先四舍五入
        $total_fee=number_format($total_fee, 2, '.', '');
        $money_fee=min($total_fee,$user_money);
        $remain_pay_fee=$total_fee-$money_fee;
        $remain_pay_fee=number_format($remain_pay_fee, 2, '.', '');
        // 需要处理小数点的数据
        $result = compact(
            "goods_amount",
            "fuel_price",
            "fuel_guaji_price",
            "litre",
            "dispatch_amount",
            "chuchang_amount",
            "discount_fee",
            "jianmian_money",
            "total_amount",
            "total_fee",
            "user_money",
            "remain_pay_fee",
            "money_fee"
        );
        // 处理小数点保留两位小数
        foreach ($result as $key => $vo) {
            $result[$key] = number_format($vo, 2, '.', '');
        }
        // 合并不需要处理小数点的
        $result = array_merge($result, compact(
            "store_name",
            "admin_id",
            "fuel_name"
        ));
        return $result;

    }

    /**
     * 创建订单
     * @param $params
     * @return mixed
     */
    public static function createOrder($params)
    {
        $user = User::info();

        // 入参
        extract($params);
        $remark = $remark ?? null;
        // 订单计算数据
        extract(self::pre($params, "create"));

        // 支付选项限制
//        $configModel = new \addons\sum\model\Config;
//        $config = $configModel->where('name','oil')->column('value', 'name');
        // 基本设置
//        $oilConfig = json_decode($config['oil'], true);
//        $pay_option=$oilConfig['pay_option'];
        $pay_option='free';//团队长充值，只有余额支付 - 20240904 改为组合支付

        // 不做限制了
//        if($user['re_times']==0){
//            new Exception('请先充值');
//        }
        if($pay_option=='balance'){//余额支付
            if($money_fee<$total_fee){
                new Exception('您的余额不足支付本订单');
            }
        }elseif($pay_option=='surplus'){
            if($money_fee==0){
                new Exception('您的余额为0请充值');
            }
        }
        if ($total_amount<=0){
            new Exception('获取油站价格失败');
        }

        $order = Db::transaction(function () use (
            $user,
            $goods_amount,
            $total_amount,
            $dispatch_amount,
            $chuchang_amount,
            $discount_fee,
            $total_fee,
            $store_id,
            $admin_id,
            $store_name,
            $fuel_id,
            $fuel_name,
            $fuel_price,
            $fuel_guaji_price,
            $litre,
            $gun_key,
            $gun_title,
            $money_fee,
            $remark
        ) {

            $orderData = [];
            $orderData['order_sn'] = self::getSn($user->id);
            $orderData['user_id'] = $user->id;
            $orderData['goods_amount'] = $goods_amount;
            $orderData['total_amount'] = $total_amount;
            $orderData['total_fee'] = $total_fee;
            $orderData['dispatch_amount'] = $dispatch_amount;
            $orderData['chuchang_amount'] = $chuchang_amount;
            $orderData['discount_fee'] = $discount_fee;
            $orderData['remain_pay_fee'] = $total_fee;
            // 油站信息
            $orderData['store_id'] = $store_id;
            $orderData['admin_id'] = $admin_id;
            $orderData['store_name'] = $store_name;
            // 油品信息
            $orderData['fuel_id'] = $fuel_id;
            $orderData['fuel_name'] = $fuel_name;
            $orderData['fuel_price'] = $fuel_price;
            $orderData['fuel_guaji_price'] = $fuel_guaji_price;
            $orderData['litre'] = $litre;
            // 油枪信息
            $orderData['gun_key'] = $gun_key;
            $orderData['gun_title'] = $gun_title;

            $orderData['status'] = 0;//测试时直接设置成已支付，后期再给为0
            $orderData['version'] = 'xyttj';//版本
            $orderData['remark'] = $remark;
            $orderData['platform'] = request()->header('platform');
            $orderData['pay_fee'] = $money_fee;          // 将余额支付部分填入已支付金额。用于后期的退款
            // $orderData['pay_fee'] = $pay_fee;          // 回调填充
            // $orderData['score_fee'] = $score_fee;          // 回调填充
            // $orderData['transaction_id'] = transaction_id;
            // $orderData['payment_json'] = payment_json;
            // $orderData['pay_type'] = pay_type;
            // $orderData['paytime'] = paytime;

            $order = new Order();
            $order->allowField(true)->save($orderData);
            //订单余额支付
            if($money_fee>0){//到这一步如何有值就是能进行余额支付
                //扣除用户余额
                User::money(-$money_fee, $user->id, 'wallet_pay', $order->id);
                $remain_pay_fee = bcsub($order->remain_pay_fee, $money_fee, 2);
                $money_data['money_fee']=$money_fee;
                $money_data['remain_pay_fee']=$remain_pay_fee;
                self::where('id', $order['id'])->update($money_data);

                if($remain_pay_fee<=0){//订单余额支付就完成了
                    $notify = [
                        'order_sn' => $order['order_sn'],
                        'transaction_id' => '',
                        'notify_time' => '',
                        'buyer_email' => '',
                        'payment_json' => '',
                        'pay_fee' => 0,
                        'pay_type' => 'wallet'              // 支付方式
                    ];
                    $order->paymentProcess($order, $notify);
                }

            }
            // 重新获取订单
            $order = self::where('id', $order['id'])->find();
            return $order;
        });

        return $order;
    }
    // 订单列表-最新订单列表-用来展示优惠信息
    public static function getNewlist($params)
    {
        $bgcbor=[
            0=>[
                'bgc'=>"#6A95EB",
                'bor'=>"#C7DAFF"
            ],
            1=>[
                'bgc'=>"#6A95EB",
                'bor'=>"#C7DAFF"
            ],
            2=>[
                'bgc'=>"#6A95EB",
                'bor'=>"#C7DAFF"
            ]
        ];
        extract($params);
        $order = (new self());
        $order = $order->payed();
        $orders = $order->order('id', 'desc')->paginate($per_page ?? 10);
        $list=[];
        $orders->each(function ($order)use($bgcbor,&$list){
            $img=Db::name('user')->where('id',$order['user_id'])->value('avatar');
            $item['src']=cdnurl($img);
            $item['num']=-$order['discount_fee'];
            $randomNumber = rand(0, 2);
            $item['bgc']=$bgcbor[$randomNumber]['bgc'];
            $item['bor']=$bgcbor[$randomNumber]['bor'];;
            unset($img);
            $list[]=$item;
        });
        return $list;
    }
    // 订单列表
    public static function getList($params)
    {
        $user = User::info();
        extract($params);
        $order = (new self())->where('user_id', $user->id)->where('total_amount','>', 0);
        switch ($type) {
            case 'all':
                $order = $order;
                break;
            case 'nopay':
                $order = $order->nopay();
                break;
            case 'payed':
                $order = $order->payedorfinish()->noaftersale();
                break;
            case 'aftersale':
                $order = $order->payed()->aftersale();
                break;
        }
        $orders = $order->order('id', 'desc')->paginate(10);
        $latitude=isset($latitude)?$latitude:null;
        $longitude=isset($longitude)?$longitude:null;
        $orders->each(function ($order)use($latitude,$longitude){
            $store = StoreModel::with('fuel')->where('id',$order['store_id']);
            if ($latitude && $longitude) {
                $store = $store->field('*, ' . getDistanceBuilder($latitude, $longitude))->order('distance', 'asc');
            }
            $store=$store->find();
            $order['store']=$store;

            $order_ext = $order['ext_arr'];
            $confirm_expired_time=$order_ext['confirm_expired_time']??0;
            $time=time();
            if($time>=$confirm_expired_time){
                $order['confirm_expired_second']=0;
            }else{
                $order['confirm_expired_second']=$confirm_expired_time-$time;
            }
            $order['order_sn_eight']=substr($order['order_sn'], -8);
        });
        return $orders;
    }

    // 订单详情
    public static function detail($params)
    {
        $user = User::info();
        extract($params);

        $order = (new self())->where('user_id', $user->id);

        if (isset($order_sn)) {
            $order = $order->where('order_sn', $order_sn);
        }
        if (isset($id)) {
            $order = $order->where('id', $id);
        }

        $order = $order->find();

        $latitude=isset($latitude)?$latitude:null;
        $longitude=isset($longitude)?$longitude:null;
        $store = StoreModel::show()->with('fuel')->where('id',$order['store_id']);
        if ($latitude && $longitude) {
            $store = $store->field('*, ' . getDistanceBuilder($latitude, $longitude))->order('distance', 'asc');
        }
        $store=$store->find();
        $order['store']=$store;

        $order_ext = $order['ext_arr'];
        $confirm_expired_time=$order_ext['confirm_expired_time']??0;
        $time=time();
        if($time>=$confirm_expired_time){
            $order['confirm_expired_second']=0;
        }else{
            $order['confirm_expired_second']=$confirm_expired_time-$time;
        }

        if (!$order) {
            new Exception('订单不存在');
        }
        $order['order_sn_eight']=substr($order['order_sn'], -8);
        return $order;
    }

    // 订单详情-转赠
    public static function detail_zz($params)
    {
        extract($params);

        $order = (new self())->where('status', 3);

        if (isset($order_sn)) {
            $order = $order->where('order_sn', $order_sn);
        }
        if (isset($id)) {
            $order = $order->where('id', $id);
        }

        $order = $order->find();

        $latitude=isset($latitude)?$latitude:null;
        $longitude=isset($longitude)?$longitude:null;
        $store = StoreModel::show()->with('fuel')->where('id',$order['store_id']);
        if ($latitude && $longitude) {
            $store = $store->field('*, ' . getDistanceBuilder($latitude, $longitude))->order('distance', 'asc');
        }
        $store=$store->find();
        $order['store']=$store;

        $order_ext = $order['ext_arr'];
        $confirm_expired_time=$order_ext['confirm_expired_time']??0;
        $time=time();
        if($time>=$confirm_expired_time){
            $order['confirm_expired_second']=0;
        }else{
            $order['confirm_expired_second']=$confirm_expired_time-$time;
        }

        if (!$order) {
            new Exception('订单不存在');
        }
        $order['order_sn_eight']=substr($order['order_sn'], -8);
        return $order;
    }

    /**
     * 支付完成回调
     * @param $order
     * @param $notify
     */
    public function paymentProcess($order, $notify)
    {
        $order->status = Order::STATUS_PAYED;
        $order->paytime = time();
        $order->transaction_id = $notify['transaction_id'];
        $order->payment_json = $notify['payment_json'];
        $order->pay_type = $notify['pay_type'];
//        $order->pay_fee = $notify['pay_fee'];
        $order->pay_fee = $order['pay_fee']+$notify['pay_fee'];//余额支付+微信支付。所以加上，获取总支付的
        $close_hour=12;
        $order_ext['confirm_expired_time'] = time() + ($close_hour * 60 * 60);
        $order->ext = json_encode($order->setExt($order, $order_ext));
        $order->save();

        $user = User::where('id', $order->user_id)->find();
        \addons\oil\model\OrderAction::operAdd($order, $user, 'user', '用户支付成功','pay');
        // 支付成功后续使用异步队列处理
//        \think\Queue::push('\addons\shopro\job\OrderPayed@payed', ['order' => $order, 'user' => $user], 'shopro-high');

        //增加小票打印
        $store=StoreModel::where('id',$order['store_id'])->find();
        $printer=PrinterModel::where('id',$store['printer_id'])->find();
        if($printer){
            $printer_aram=[];
            $printer_aram['origin_id']=$order['order_sn'];
            $last4 = substr($order['order_sn'], - 4);
            $printer_aram['order_sn_last4']=$last4;
            $printer_aram['machine_code']=$printer['machine_code'];
            $printer_aram['store_name']=$order['store_name'];
            $printer_aram['order_time']=date('Y-m-d H:i:s',$order['createtime']);
            $printer_aram['order_sn']=$order['order_sn'];
            $printer_aram['gun_title']=$order['gun_title'];
            $printer_aram['fuel_name']=$order['fuel_name'];
            $printer_aram['fuel_price']=$order['fuel_price'];
            $printer_aram['fuel_guaji_price']=$order['fuel_guaji_price'];
            $printer_aram['litre']=$order['litre'];
            $printer_aram['goods_amount']=$order['goods_amount'];
            $printer_aram['dispatch_amount']=$order['dispatch_amount'];
            $printer_aram['discount_fee']=$order['discount_fee']??0;
            $printer_aram['total_fee']=$order['total_fee'];
            $printer_aram['version']=$order['version'];
            $template_slug="oil_order";
            PrinterService::submit($printer_aram,$template_slug);
        }

        return $order;
    }

    // 开始退款
    public static function startRefund($order, $refund_money, $user = null, $remark = '') {
        // 订单退款前
        $data = ['order' => $order];
//        \think\Hook::listen('order_refund_before', $data);

        \addons\oil\model\OrderAction::operAdd($order, $user, ($user ? 'admin' : 'system'), $remark . '退款金额：' . $refund_money,'refund_finish');
        \think\Log::write('refund-aaaa');
        \app\admin\model\oil\order\Order::refund($order, $refund_money, $remark);

        // 订单退款后
        $data = ['order' => $order];
        \think\Hook::listen('order_refund_after', $data);
    }

    // 退款
    public static function refund($order, $refund_money, $remark = '')
    {
        $remark='';//不让显示退款原因
        // 生成退款单
        $refundLog = new RefundLog();
        $refundLog->order_sn = $order->order_sn;
        $refundLog->refund_sn = RefundLog::getSn($order->user_id);
        $refundLog->pay_fee = $order->pay_fee;
        $refundLog->refund_fee = $refund_money;
        $refundLog->pay_type = $order->pay_type;
        $refundLog->save();
//        \think\Log::write('refund-log' . json_encode($refundLog));
        // 退款
        $money_fee=$order['money_fee'];//余额支付金额
        $remain_pay_fee=$order['remain_pay_fee'];//在线支付金额

//        \think\Log::write('money_fee:' . $money_fee);
//        \think\Log::write('remain_pay_fee:' . $remain_pay_fee);

        if($money_fee>0){
            // 余额退款
            \addons\sum\model\User::money($money_fee, $order->user_id, 'wallet_refund', $order->id, '', [
                'order_id' => $order->id,
                'order_sn' => $order->order_sn,
            ]);
        }

//        \think\Log::write('refund-order' . json_encode($order));

        if($remain_pay_fee>0){
            // 微信退款
            $pay_type='wechat';
            $payOrder=Db::name('sum_pay_order')->where('table_name','sum_oil_order')->where('table_id',$order['id'])->where('ispay',1)->find();
            \think\Log::write('refund-pay-order' . json_encode($payOrder));
            // 退款数据
            $order_data = [
                'out_trade_no' => $payOrder['out_trade_no']
            ];
            $total_fee = intval($remain_pay_fee * 100);
            $refund_fee = intval($remain_pay_fee * 100);
            $order_data = array_merge($order_data, [
                'out_refund_no' => $refundLog->refund_sn,
                'amount'=>[
                    'refund' => $refund_fee,
                    'total' => $total_fee,
                    'currency' => 'CNY',
                ],
            ]);

            $notify_url = request()->domain() . '/addons/sum/pay/notifyr/payment/' . $pay_type . '/platform/' . $order->platform;
            \think\Log::write('refund-order_data' . json_encode($order_data));
            $pay = new \addons\sum\library\PayService($pay_type, $order->platform, $notify_url);

            $result = $pay->refund($order_data);

            \think\Log::write('refund-result' . json_encode($result));
            if (!$result['code']) {
                // 如果有微信支付-直接有个返回再回调处理
                return true;
            } else {
                throw new \Exception($result['message']);
            }
        }
        // 如果有微信支付-直接有个返回再回调处理
        self::refundFinish($order, $refundLog);
        return true;
    }

    // 退款-作废
    public static function refund_exit($order, $refund_money, $remark = '')
    {
        $remark='';//不让显示退款原因
        // 生成退款单
        $refundLog = new RefundLog();
        $refundLog->order_sn = $order->order_sn;
        $refundLog->refund_sn = RefundLog::getSn($order->user_id);
        $refundLog->pay_fee = $order->pay_fee;
        $refundLog->refund_fee = $refund_money;
        $refundLog->pay_type = $order->pay_type;
        $refundLog->save();

        if ($order->pay_type == 'wechat' || $order->pay_type == 'alipay') {
            // 微信|支付宝退款
            $payOrder=Db::name('sum_pay_order')->where('table_name','sum_oil_order')->where('table_id',$order['id'])->where('ispay',1)->find();
            // 退款数据
            $order_data = [
                'out_trade_no' => $payOrder['out_trade_no']
            ];

            if ($order->pay_type == 'wechat') {
                $total_fee = $order->pay_fee * 100;
                $refund_fee = $refund_money * 100;

                $order_data = array_merge($order_data, [
                    'out_refund_no' => $refundLog->refund_sn,
                    'total_fee' => $total_fee,
                    'refund_fee' => $refund_fee,
                    'refund_desc' => $remark,
                ]);
            } else {
                $order_data = array_merge($order_data, [
                    'out_request_no' => $refundLog->refund_sn,
                    'refund_amount' => $refund_money,
                ]);
            }

            $notify_url = request()->domain() . '/addons/sum/pay/notifyr/payment/' . $order->pay_type . '/platform/' . $order->platform;

            $pay = new \addons\sum\library\PayService($order->pay_type, $order->platform, $notify_url);
            $result = $pay->refund($order_data);

            \think\Log::write('refund-result' . json_encode($result));


            if ($order->pay_type == 'wechat') {
                // 微信通知回调 pay->notifyr
                if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
                    return true;
                } else {
                    throw new \Exception($result['return_msg']);
                }
            } else {
                // 支付宝通知回调 pay->notifyx
                if ($result['code'] == "10000") {
                    return true;
                } else {
                    throw new \Exception($result['msg']);
                }
            }

            // {        // 微信返回结果
            //     "return_code":"SUCCESS",
            //     "return_msg":"OK",
            //     "appid":"wx39cd0799d4567dd0",
            //     "mch_id":"1481069012",
            //     "nonce_str":"huW9eIAb5BDPn0Ma",
            //     "sign":"250316740B263FE53F5DFF50AF5A8FA1",
            //     "result_code":"SUCCESS",
            //     "transaction_id":"4200000497202004072822298902",
            //     "out_trade_no":"202010300857029180027000",
            //     "out_refund_no":"1586241595",
            //     "refund_id":"50300603862020040700031444448",
            //     "refund_channel":[],
            //     "refund_fee":"1",
            //     "coupon_refund_fee":"0",
            //     "total_fee":"1",
            //     "cash_fee":"1",
            //     "coupon_refund_count":"0",
            //     "cash_refund_fee":"1
            // }

            // {        // 支付宝返回结果
            //     "code": "10000",
            //     "msg": "Success",
            //     "buyer_logon_id": "157***@163.com",
            //     "buyer_user_id": "2088902485164146",
            //     "fund_change": "Y",
            //     "gmt_refund_pay": "2020-08-15 16:11:45",
            //     "out_trade_no": "202002460317545607015300",
            //     "refund_fee": "0.01",
            //     "send_back_fee": "0.00",
            //     "trade_no": "2020081522001464141438570535"
            // }
        } else if ($order->pay_type == 'wallet') {
//            Log::info(['zzzztest'=>['aa'=>$refund_money,'bb'=>$order->user_id]]);
            // 余额退款
            if ($refund_money != 0) {
                \addons\sum\model\User::money($refund_money, $order->user_id, 'wallet_refund', $order->id, '', [
                    'order_id' => $order->id,
                    'order_sn' => $order->order_sn,
                ]);
            }

            self::refundFinish($order, $refundLog);

            return true;
        } else if ($order->pay_type == 'score') {
            // 积分退款，暂不支持积分退款
            return false;
        }
    }
    public static function refundFinish($order, $refundLog)
    {
        // 退款完成
        $refundLog->status = 1;
        $refundLog->save();

        // 退款完成
        $order->refund_status = \app\admin\model\oil\order\Order::REFUND_STATUS_FINISH;    // 退款完成
        $order->ext = json_encode($order->setExt($order, ['refund_time' => time()]));      // 退款完成时间
        $order->save();
        \addons\oil\model\OrderAction::operAdd($order, null, 'admin', '退款成功');
    }
    // 确认加油订单
    public static function operConfirm($params)
    {
        $user = User::info();
        extract($params);
        $order = self::where('user_id', $user->id)->where('id', $id)->noget()->find();
        if (!$order) {
            new Exception('订单不存在或已确认');
        }
        // 订单取消
        $order = (new self)->doConfirm($order, $user);
        return $order;
    }

    /**
     * 确认订单操作
     * @return mixed
     */
    public function doConfirm($order, $user, $type = 'user') {
        $order = Db::transaction(function () use ($order, $user, $type) {
            $data = ['order' => $order];
//            \think\Hook::listen('order_confirm_before', $hookData);

            $order->status = Order::STATUS_FINISH;        // 完成订单
            $order->ext = json_encode($order->setExt($order, ['confirm_time' => time()]));      // 完成时间
            $order->save();



            \addons\oil\model\OrderAction::operAdd($order, $user, $type, ($type == 'user' ? '用户' : '管理员') . '确认订单','confirm');
            $data = ['order' => $order];
            \think\Hook::listen('order_confirm_after', $data);
            return $order;
        });
        return $order;
    }

    // 确认加油订单-by核销
    public static function operConfirmByHexiao($params)
    {
        extract($params);
        $order = self::where('id', $id)->noget()->find();
        if (!$order) {
            new Exception('订单不存在或已确认');
        }
        // 订单取消
        $order = (new self)->doConfirmByHexiao($order);
        return $order;
    }

    /**
     * 确认订单操作-by核销
     * @return mixed
     */
    public function doConfirmByHexiao($order) {
        $order = Db::transaction(function () use ($order) {
            $data = ['order' => $order];
//            \think\Hook::listen('order_confirm_before', $hookData);

            $order->status = Order::STATUS_FINISH;        // 完成订单
            $order->ext = json_encode($order->setExt($order, ['confirm_time' => time()]));      // 完成时间
            $order->save();
            \addons\oil\model\OrderAction::operAdd($order, '', 'admin',  '系统确认订单','confirm');
            $data = ['order' => $order];
            \think\Hook::listen('order_confirm_after', $data);
            return $order;
        });
        return $order;
    }



    // 取消订单
    public static function operCancel($params)
    {
        $user = User::info();
        extract($params);
        $order = self::where('user_id', $user->id)->where('id', $id)->nopay()->find();
        if (!$order) {
            new Exception('订单不存在或已取消');
        }
        // 订单取消
        $order = (new self)->doCancel($order, $user);
        return $order;
    }


    /**
     * 取消订单操作
     * @return mixed
     */
    public function doCancel($order, $user, $type = 'user') {
        $order = Db::transaction(function () use ($order, $user, $type) {
            $data = ['order' => $order];
//            \think\Hook::listen('order_cancel_before', $data);

            $order->status = Order::STATUS_CANCEL;        // 取消订单
            $order->ext = json_encode($order->setExt($order, ['cancel_time' => time()]));      // 取消时间
            $order->save();
            \addons\oil\model\OrderAction::operAdd($order, $user, $type, ($type == 'user' ? '用户' : '管理员') . '取消订单','cancel');
            // 订单取消，退回使用的用户，等
            $data = ['order' => $order];
            \think\Hook::listen('order_cancel_after', $data);
            return $order;
        });
        return $order;
    }

    // 分享转赠订单
    public static function operShare($params)
    {
        $user = User::info();
        extract($params);
        $order = self::where('user_id', $user->id)->where('id', $id)->canShare()->find();
        if (!$order) {
            new Exception('订单不支持转赠');
        }
        // 订单转赠
        $order = (new self)->doShare($order, $user);
        return $order;
    }

    /**
     * 转赠订单操作
     * @return mixed
     */
    public function doShare($order, $user, $type = 'user') {
        $order = Db::transaction(function () use ($order, $user, $type) {
            $data = ['order' => $order];
            $order->status = Order::STATUS_SHARE;        // 已转赠
            $order->ext = json_encode($order->setExt($order, ['share_time' => time(),'share_expire_time'=>time()+86400]));      // 取消时间
            $order->save();
            \addons\oil\model\OrderAction::operAdd($order, $user, $type, ($type == 'user' ? '用户' : '管理员') . '转赠订单','share');
            $data = ['order' => $order];
            \think\Hook::listen('order_share_after', $data);
            return $order;
        });
        return $order;
    }

    // 领取转赠订单
    public static function operReceive($params)
    {
        $user = User::info();
        extract($params);
        //不能领取自己的订单
        $order = self::where('id', $id)->where('user_id','<>',$user['id'])->canReceive()->find();
        if (!$order) {
            new Exception('订单不能领取');
        }
        // 订单转赠领取
        $order = (new self)->doReceive($order, $user);
        return $order;
    }

    /**
     * 转赠订单领取操作
     * @return mixed
     */
    public function doReceive($order, $user, $type = 'user') {
        $order_new = Db::transaction(function () use ($order, $user, $type) {
            $data = ['order' => $order];
            $order->is_received = 1;        // 已领取
            $order->to_user_id = $user['id'];        // 领取用户id
            $order->to_user_oil_num = $user['oil_num'];        // 领取用户油桶号
            $order->to_user_mobile = $user['mobile'];        // 领取用户手机号
            $order->ext = json_encode($order->setExt($order, ['receive_time' => time()]));      // 领取时间
            $order->save();
            \addons\oil\model\OrderAction::operAdd($order, $user, $type, ($type == 'user' ? '用户' : '管理员') . '领取订单','receive');

            //生成新订单
            $orderData = [];
            $orderData['order_sn'] = self::getSn($user->id);
            $orderData['user_id'] = $user->id;
            $orderData['goods_amount'] = $order['goods_amount'];
            $orderData['total_amount'] = $order['total_amount'];
            $orderData['total_fee'] = $order['total_fee'];
            $orderData['dispatch_amount'] = $order['dispatch_amount'];
            $orderData['remain_pay_fee'] = $order['remain_pay_fee'];
            // 油站信息
            $orderData['store_id'] = $order['store_id'];
            $orderData['admin_id'] = $order['admin_id'];
            $orderData['store_name'] = $order['store_name'];
            // 油品信息
            $orderData['fuel_id'] = $order['fuel_id'];
            $orderData['fuel_name'] = $order['fuel_name'];
            $orderData['fuel_price'] = $order['fuel_price'];
            $orderData['litre'] = $order['litre'];
            // 油枪信息
            $orderData['gun_key'] = $order['gun_key'];
            $orderData['gun_title'] = $order['gun_title'];
            $orderData['status'] = 1;
            $orderData['version'] = $order['version'];//版本

            $orderData['remark'] = '';
            $orderData['platform'] = request()->header('platform');
            $orderData['buyorgive'] = 1;
            $from_user=User::where('id',$order['user_id'])->find();
            $orderData['from_user_id'] = $from_user['id'];
            $orderData['from_user_mobile'] = $from_user['mobile'];
            $orderData['from_user_oil_num'] = $from_user['oil_num'];
            $orderData['original_id'] = $order['id'];
            //转赠订单都算已支付且都是余额支付-用于退款时退到余额
            $orderData['pay_fee'] = $order['pay_fee'];

            $orderData['refund_status'] = $order['refund_status'];

            $orderData['pay_type'] = 'wallet';

            $order_new = new Order();
            $order_new->allowField(true)->save($orderData);

//            $data = ['order' => $order];
//            \think\Hook::listen('order_receive_after', $data);

            //增加小票打印-新订单的小票
            $store=StoreModel::where('id',$order_new['store_id'])->find();
            $printer=PrinterModel::where('id',$store['printer_id'])->find();
            if($printer){
                $printer_aram=[];
                $printer_aram['origin_id']=$order_new['order_sn'];
                $last4 = substr($order_new['order_sn'], - 4);
                $printer_aram['order_sn_last4']=$last4;
                $printer_aram['machine_code']=$printer['machine_code'];
                $printer_aram['store_name']=$order_new['store_name'];
                $printer_aram['order_time']=date('Y-m-d H:i:s',$order_new['createtime']);
                $printer_aram['order_sn']=$order_new['order_sn'];
                $printer_aram['gun_title']=$order_new['gun_title'];
                $printer_aram['fuel_name']=$order_new['fuel_name'];
                $printer_aram['fuel_price']=$order_new['fuel_price'];
                $printer_aram['fuel_guaji_price']=$order_new['fuel_guaji_price'];
                $printer_aram['litre']=$order_new['litre'];
                $printer_aram['goods_amount']=$order_new['goods_amount'];
                $printer_aram['dispatch_amount']=$order_new['dispatch_amount'];
                $printer_aram['discount_fee']=$order_new['discount_fee']??0;
                $printer_aram['total_fee']=$order_new['total_fee'];
                $printer_aram['version']=$order_new['version'];
                $template_slug="oil_order";
                PrinterService::submit($printer_aram,$template_slug);
            }

            return $order_new;
        });
        return $order_new;
    }


    public function setExt($order, $field, $origin = []) {
        $newExt = array_merge($origin, $field);

        $orderExt = $order['ext_arr'];

        return array_merge($orderExt, $newExt);
    }
}
